<?php

namespace Twilio\Tests\Unit;

use Twilio\TaskRouter\WorkflowConfiguration;
use Twilio\TaskRouter\WorkflowRule;
use Twilio\TaskRouter\WorkflowRuleTarget;
use Twilio\Tests\Unit\UnitTest;

class WorkflowTest extends UnitTest {

	public function testDefaultRuleTarget() {
		$everyoneQueue = "WQf6724bd5005b30eeb6ea990c3e59e536";
		$defaultTarget = new WorkflowRuleTarget( $everyoneQueue );
		$this->assertEquals( $defaultTarget->queue, "WQf6724bd5005b30eeb6ea990c3e59e536" );
		$this->assertEquals( $defaultTarget->priority, null );
		$this->assertEquals( $defaultTarget->timeout, null );
		$this->assertEquals( $defaultTarget->expression, null );
	}

	public function testSimpleRuleTarget() {
		$everyoneQueue          = "WQf6724bd5005b30eeb6ea990c3e59e536";
		$priority               = 10;
		$timeout                = 60;
		$filterWorkerExpression = null;
		$ruleTarget             = new WorkflowRuleTarget( $everyoneQueue, $priority, $timeout, $filterWorkerExpression );
		$this->assertEquals( $ruleTarget->queue, "WQf6724bd5005b30eeb6ea990c3e59e536" );
		$this->assertEquals( $ruleTarget->priority, $priority );
		$this->assertEquals( $ruleTarget->timeout, $timeout );
		$this->assertEquals( $ruleTarget->expression, $filterWorkerExpression );
	}

	public function testFilterWorkerRuleTarget() {
		$everyoneQueue          = "WQf6724bd5005b30eeb6ea990c3e59e536";
		$priority               = 10;
		$timeout                = 60;
		$filterWorkerExpression = "task.language IN worker.languages";
		$ruleTarget             = new WorkflowRuleTarget( $everyoneQueue, $priority, $timeout, $filterWorkerExpression );
		$this->assertEquals( $ruleTarget->queue, "WQf6724bd5005b30eeb6ea990c3e59e536" );
		$this->assertEquals( $ruleTarget->priority, $priority );
		$this->assertEquals( $ruleTarget->timeout, $timeout );
		$this->assertEquals( $ruleTarget->expression, $filterWorkerExpression );
	}

	public function testSimpleRule() {
		$salesQueue     = "WQf6724bd5005b30eeb6ea990c3e59e536";
		$salesTarget    = new WorkflowRuleTarget( $salesQueue );
		$expression     = "type=='sales'";
		$friendlyName   = "Sales";
		$salesTargets[] = $salesTarget;
		$salesRule      = new WorkflowRule( $expression, $salesTargets, $friendlyName );
		$this->assertEquals( $salesRule->expression, $expression );
		$this->assertEquals( $salesRule->friendly_name, $friendlyName );
		$this->assertEquals( $salesRule->targets[0], $salesTarget );
	}

	public function testFullWorkflow() {
		$salesQueue     = "WQf6724bd5005b30eeb6ea990c3e59e536";
		$marketingQueue = "WQ8c62f84b61ccfa6a333757cd508f0aae";
		$supportQueue   = "WQ5940dc0da87eaf6e3321d62041d4403b";
		$everyoneQueue  = "WQ6d29383312b24bd898a8df32779fc043";

		$defaultTarget = new WorkflowRuleTarget( $everyoneQueue );

		$salesTargets   = array();
		$salesTarget    = new WorkflowRuleTarget( $salesQueue );
		$salesTargets[] = $salesTarget;
		$salesRule      = new WorkflowRule( "type=='sales'", $salesTargets, 'Sales' );

		$marketingTargets   = array();
		$marketingTarget    = new WorkflowRuleTarget( $marketingQueue );
		$marketingTargets[] = $marketingTarget;
		$marketingRule      = new WorkflowRule( "type=='marketing'", $marketingTargets, 'Marketing' );

		$supportTargets   = array();
		$supportTarget    = new WorkflowRuleTarget( $supportQueue );
		$supportTargets[] = $supportTarget;
		$supportRule      = new WorkflowRule( "type=='support'", $supportTargets, 'Support' );

		$rules[] = $salesRule;
		$rules[] = $marketingRule;
		$rules[] = $supportRule;

		$configuration = new WorkflowConfiguration( $rules, $defaultTarget );
		$json          = $configuration->toJSON();

		$expectedJsonString = "{
				\"task_routing\":{
				  \"filters\":[
					 {
						\"expression\":\"type=='sales'\",
						\"targets\":[
						   {
							  \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\"
						   }
						],
						\"friendly_name\":\"Sales\"
					 },
					 {
						\"expression\":\"type=='marketing'\",
						\"targets\":[
						   {
							  \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\"
						   }
						],
						\"friendly_name\":\"Marketing\"
					 },
					 {
						\"expression\":\"type=='support'\",
						\"targets\":[
						   {
							  \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\"
						   }
						],
						\"friendly_name\":\"Support\"
					 }
				  ],
				  \"default_filter\":{
					 \"queue\":\"WQ6d29383312b24bd898a8df32779fc043\"
				  }
				}
			}";

		// getting a trimmed, simple string
		$jsonObject   = json_decode( $expectedJsonString );
		$expectedJson = json_encode( $jsonObject );

		$this->assertEquals( $json, $expectedJson );
	}

	public function testFullWorkflowWithTimeouts() {
		$salesQueue     = "WQf6724bd5005b30eeb6ea990c3e59e536";
		$marketingQueue = "WQ8c62f84b61ccfa6a333757cd508f0aae";
		$supportQueue   = "WQ5940dc0da87eaf6e3321d62041d4403b";
		$everyoneQueue  = "WQ6d29383312b24bd898a8df32779fc043";

		$defaultTarget = new WorkflowRuleTarget( $everyoneQueue );

		$salesTargets   = array();
		$salesTarget1   = new WorkflowRuleTarget( $salesQueue, 5, 30 );
		$salesTarget2   = new WorkflowRuleTarget( $salesQueue, 10 );
		$salesTargets[] = $salesTarget1;
		$salesTargets[] = $salesTarget2;
		$salesRule      = new WorkflowRule( "type=='sales'", $salesTargets, 'Sales' );

		$marketingTargets   = array();
		$marketingTarget1   = new WorkflowRuleTarget( $marketingQueue, 1, 120 );
		$marketingTarget2   = new WorkflowRuleTarget( $marketingQueue, 3 );
		$marketingTargets[] = $marketingTarget1;
		$marketingTargets[] = $marketingTarget2;
		$marketingRule      = new WorkflowRule( "type=='marketing'", $marketingTargets, 'Marketing' );

		$supportTargets   = array();
		$supportTarget1   = new WorkflowRuleTarget( $supportQueue, 10, 30 );
		$supportTarget2   = new WorkflowRuleTarget( $supportQueue, 15 );
		$supportTargets[] = $supportTarget1;
		$supportTargets[] = $supportTarget2;
		$supportRule      = new WorkflowRule( "type=='support'", $supportTargets, 'Support' );

		$rules[] = $salesRule;
		$rules[] = $marketingRule;
		$rules[] = $supportRule;

		$configuration = new WorkflowConfiguration( $rules, $defaultTarget );
		$json          = $configuration->toJSON();

		$expectedJsonString = "{
				\"task_routing\":{
				  \"filters\":[
					 {
						\"expression\":\"type=='sales'\",
						\"targets\":[
						   {
							  \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
							  \"priority\": 5,
							  \"timeout\": 30
						   },
						   {
							  \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
							  \"priority\": 10
						   }
						],
						\"friendly_name\":\"Sales\"
					 },
					 {
						\"expression\":\"type=='marketing'\",
						\"targets\":[
						   {
							  \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
							  \"priority\": 1,
							  \"timeout\": 120
						   },
						   {
							  \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
							  \"priority\": 3
						   }
						],
						\"friendly_name\":\"Marketing\"
					 },
					 {
						\"expression\":\"type=='support'\",
						\"targets\":[
						   {
							  \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
							  \"priority\": 10,
							  \"timeout\": 30
						   },
						   {
							  \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
							  \"priority\": 15
						   }
						],
						\"friendly_name\":\"Support\"
					 }
				  ],
				  \"default_filter\":{
					 \"queue\":\"WQ6d29383312b24bd898a8df32779fc043\"
				  }
				}
			}";

		// getting a trimmed, simple string
		$jsonObject   = json_decode( $expectedJsonString );
		$expectedJson = json_encode( $jsonObject );

		$this->assertEquals( $json, $expectedJson );
	}

	public function testParseWorkflow() {
		$json = "{
				\"task_routing\":{
				  \"filters\":[
					 {
						\"expression\":\"type=='sales'\",
						\"targets\":[
						   {
							  \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
							  \"priority\": 5,
							  \"timeout\": 30
						   },
						   {
							  \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
							  \"priority\": 10
						   }
						],
						\"friendly_name\":\"Sales\"
					 },
					 {
						\"expression\":\"type=='marketing'\",
						\"targets\":[
						   {
							  \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
							  \"priority\": 1,
							  \"timeout\": 120
						   },
						   {
							  \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
							  \"priority\": 3
						   }
						],
						\"friendly_name\":\"Marketing\"
					 },
					 {
						\"expression\":\"type=='support'\",
						\"targets\":[
						   {
							  \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
							  \"priority\": 10,
							  \"timeout\": 30
						   },
						   {
							  \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
							  \"priority\": 15
						   }
						],
						\"friendly_name\":\"Support\"
					 }
				  ],
				  \"default_filter\":{
					 \"queue\":\"WQ6d29383312b24bd898a8df32779fc043\"
				  }
				}
			}";

		$config            = WorkflowConfiguration::fromJson( $json );
		$taskRoutingConfig = WorkflowConfiguration::parse( $json )->task_routing;

		$this->assertEquals( 3, count( $taskRoutingConfig->filters ) );
		$this->assertEquals( 3, count( $config->filters ) );
		$this->assertEquals( 1, count( $config->default_filter ) );
		// sales assertions
		$this->assertEquals( "type=='sales'", $config->filters[0]->expression );
		$this->assertEquals( "Sales", $config->filters[0]->friendly_name );
		$this->assertEquals( 2, count( $config->filters[0]->targets ) );
		$this->assertEquals( "WQf6724bd5005b30eeb6ea990c3e59e536", $config->filters[0]->targets[0]->queue );
		$this->assertEquals( 5, $config->filters[0]->targets[0]->priority );
		$this->assertEquals( 30, $config->filters[0]->targets[0]->timeout );
		$this->assertEquals( "WQf6724bd5005b30eeb6ea990c3e59e536", $config->filters[0]->targets[1]->queue );
		$this->assertEquals( 10, $config->filters[0]->targets[1]->priority );
		// marketing assertions
		$this->assertEquals( "type=='marketing'", $config->filters[1]->expression );
		$this->assertEquals( "Marketing", $config->filters[1]->friendly_name );
		$this->assertEquals( 2, count( $config->filters[1]->targets ) );
		$this->assertEquals( "WQ8c62f84b61ccfa6a333757cd508f0aae", $config->filters[1]->targets[0]->queue );
		$this->assertEquals( 1, $config->filters[1]->targets[0]->priority );
		$this->assertEquals( 120, $config->filters[1]->targets[0]->timeout );
		$this->assertEquals( "WQ8c62f84b61ccfa6a333757cd508f0aae", $config->filters[1]->targets[1]->queue );
		$this->assertEquals( 3, $config->filters[1]->targets[1]->priority );
		// support assertions
		$this->assertEquals( "type=='support'", $config->filters[2]->expression );
		$this->assertEquals( "Support", $config->filters[2]->friendly_name );
		$this->assertEquals( 2, count( $config->filters[2]->targets ) );
		$this->assertEquals( "WQ5940dc0da87eaf6e3321d62041d4403b", $config->filters[2]->targets[0]->queue );
		$this->assertEquals( 10, $config->filters[2]->targets[0]->priority );
		$this->assertEquals( 30, $config->filters[2]->targets[0]->timeout );
		$this->assertEquals( "WQ5940dc0da87eaf6e3321d62041d4403b", $config->filters[2]->targets[1]->queue );
		$this->assertEquals( 15, $config->filters[2]->targets[1]->priority );
		// default filter
		$this->assertEquals( "WQ6d29383312b24bd898a8df32779fc043", $config->default_filter->queue );
	}

	public function testParseWorkflowFilterFriendlyName() {
		$json = "{
				\"task_routing\":{
				  \"filters\":[
					 {
						\"expression\":\"type=='sales'\",
						\"targets\":[
						   {
							  \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
							  \"priority\": 5,
							  \"timeout\": 30
						   },
						   {
							  \"queue\":\"WQf6724bd5005b30eeb6ea990c3e59e536\",
							  \"priority\": 10
						   }
						],
						\"filter_friendly_name\":\"Sales\"
					 },
					 {
						\"expression\":\"type=='marketing'\",
						\"targets\":[
						   {
							  \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
							  \"priority\": 1,
							  \"timeout\": 120
						   },
						   {
							  \"queue\":\"WQ8c62f84b61ccfa6a333757cd508f0aae\",
							  \"priority\": 3
						   }
						],
						\"filter_friendly_name\":\"Marketing\"
					 },
					 {
						\"expression\":\"type=='support'\",
						\"targets\":[
						   {
							  \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
							  \"priority\": 10,
							  \"timeout\": 30
						   },
						   {
							  \"queue\":\"WQ5940dc0da87eaf6e3321d62041d4403b\",
							  \"priority\": 15
						   }
						],
						\"filter_friendly_name\":\"Support\"
					 }
				  ],
				  \"default_filter\":{
					 \"queue\":\"WQ6d29383312b24bd898a8df32779fc043\"
				  }
				}
			}";

		$config            = WorkflowConfiguration::fromJson( $json );
		$taskRoutingConfig = WorkflowConfiguration::parse( $json )->task_routing;

		$this->assertEquals( 3, count( $taskRoutingConfig->filters ) );
		$this->assertEquals( 3, count( $config->filters ) );
		$this->assertEquals( 1, count( $config->default_filter ) );
		// sales assertions
		$this->assertEquals( "type=='sales'", $config->filters[0]->expression );
		$this->assertEquals( "Sales", $config->filters[0]->friendly_name );
		$this->assertEquals( 2, count( $config->filters[0]->targets ) );
		$this->assertEquals( "WQf6724bd5005b30eeb6ea990c3e59e536", $config->filters[0]->targets[0]->queue );
		$this->assertEquals( 5, $config->filters[0]->targets[0]->priority );
		$this->assertEquals( 30, $config->filters[0]->targets[0]->timeout );
		$this->assertEquals( "WQf6724bd5005b30eeb6ea990c3e59e536", $config->filters[0]->targets[1]->queue );
		$this->assertEquals( 10, $config->filters[0]->targets[1]->priority );
		// marketing assertions
		$this->assertEquals( "type=='marketing'", $config->filters[1]->expression );
		$this->assertEquals( "Marketing", $config->filters[1]->friendly_name );
		$this->assertEquals( 2, count( $config->filters[1]->targets ) );
		$this->assertEquals( "WQ8c62f84b61ccfa6a333757cd508f0aae", $config->filters[1]->targets[0]->queue );
		$this->assertEquals( 1, $config->filters[1]->targets[0]->priority );
		$this->assertEquals( 120, $config->filters[1]->targets[0]->timeout );
		$this->assertEquals( "WQ8c62f84b61ccfa6a333757cd508f0aae", $config->filters[1]->targets[1]->queue );
		$this->assertEquals( 3, $config->filters[1]->targets[1]->priority );
		// support assertions
		$this->assertEquals( "type=='support'", $config->filters[2]->expression );
		$this->assertEquals( "Support", $config->filters[2]->friendly_name );
		$this->assertEquals( 2, count( $config->filters[2]->targets ) );
		$this->assertEquals( "WQ5940dc0da87eaf6e3321d62041d4403b", $config->filters[2]->targets[0]->queue );
		$this->assertEquals( 10, $config->filters[2]->targets[0]->priority );
		$this->assertEquals( 30, $config->filters[2]->targets[0]->timeout );
		$this->assertEquals( "WQ5940dc0da87eaf6e3321d62041d4403b", $config->filters[2]->targets[1]->queue );
		$this->assertEquals( 15, $config->filters[2]->targets[1]->priority );
		// default filter
		$this->assertEquals( "WQ6d29383312b24bd898a8df32779fc043", $config->default_filter->queue );
	}
}
